summaryrefslogtreecommitdiffstats
path: root/src/Simulator/IncrementalRedstoneSimulator/RedstoneWireHandler.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/Simulator/IncrementalRedstoneSimulator/RedstoneWireHandler.h')
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator/RedstoneWireHandler.h60
1 files changed, 43 insertions, 17 deletions
diff --git a/src/Simulator/IncrementalRedstoneSimulator/RedstoneWireHandler.h b/src/Simulator/IncrementalRedstoneSimulator/RedstoneWireHandler.h
index 27e5a965c..e7666f560 100644
--- a/src/Simulator/IncrementalRedstoneSimulator/RedstoneWireHandler.h
+++ b/src/Simulator/IncrementalRedstoneSimulator/RedstoneWireHandler.h
@@ -42,20 +42,22 @@ public:
cVector3iArray GetTerracingConnectionOffsets(cWorld & a_World, const Vector3i a_Position) const
{
- cVector3iArray RelativePositions;
- auto YPTerraceBlock = a_World.GetBlock(a_Position + OffsetYP());
- bool IsYPTerracingBlocked = cBlockInfo::IsSolid(YPTerraceBlock) && !cBlockInfo::IsTransparent(YPTerraceBlock);
+ auto RelativePositions = GetRelativeLaterals();
+ const auto YPTerraceBlock = a_World.GetBlock(a_Position + OffsetYP());
+ const bool IsYPTerracingBlocked = cBlockInfo::IsSolid(YPTerraceBlock) && !cBlockInfo::IsTransparent(YPTerraceBlock);
for (const auto & Adjacent : GetRelativeLaterals())
{
if (
+ // A block above us blocks all YP terracing, so the check is static in the loop
!IsYPTerracingBlocked &&
(a_World.GetBlock(a_Position + Adjacent + OffsetYP()) == E_BLOCK_REDSTONE_WIRE)
- )
+ )
{
RelativePositions.emplace_back(Adjacent + OffsetYP());
}
- auto YMTerraceBlock = a_World.GetBlock(a_Position + Adjacent);
+
+ const auto YMTerraceBlock = a_World.GetBlock(a_Position + Adjacent);
if (
// IsYMTerracingBlocked (i.e. check block above lower terracing position, a.k.a. just the plain adjacent)
(!cBlockInfo::IsSolid(YMTerraceBlock) || cBlockInfo::IsTransparent(YMTerraceBlock)) &&
@@ -83,31 +85,55 @@ public:
a_Meta++;
}
- if ((a_QueryPosition != (a_Position + OffsetYM())) && !IsDirectlyConnectingMechanism( a_QueryBlockType, a_Meta, a_QueryPosition - a_Position))
+ // Wires always deliver power to the block underneath, and any directly connecting mechanisms
+ if (
+ (a_QueryPosition != (a_Position + OffsetYM())) &&
+ !IsDirectlyConnectingMechanism(a_QueryBlockType, a_World.GetBlockMeta(a_QueryPosition), a_QueryPosition - a_Position)
+ )
{
+ /*
+ Okay, we do not directly connect to the wire.
+ If there are no DC mechanisms at all, the wire powers all laterals. Great, we fall out the loop.
+ If there is one DC mechanism, the wire "goes straight" along the axis of the wire and mechanism.
+ The only possible way for us to be powered is for us to be on the opposite end, with the wire pointing towards us.
+ If there is more than one DC, no non-DCs are powered.
+ */
+
Vector3i PotentialOffset;
bool FoundOneBorderingMechanism = false;
- for (const auto & Offset : StaticAppend(GetRelativeLaterals(), GetTerracingConnectionOffsets(a_World, a_Position)))
+ for (const auto & Offset : GetTerracingConnectionOffsets(a_World, a_Position))
{
- if (IsDirectlyConnectingMechanism(a_World.GetBlock(Offset + a_Position), a_Meta, Offset))
+ BLOCKTYPE Block;
+ NIBBLETYPE Meta;
+
+ if (
+ !a_World.GetBlockTypeMeta(Offset + a_Position, Block, Meta) ||
+ !IsDirectlyConnectingMechanism(Block, Meta, Offset)
+ )
{
- if (FoundOneBorderingMechanism)
- {
- return 0;
- }
- else
- {
- FoundOneBorderingMechanism = true;
- PotentialOffset = { -Offset.x, 0, -Offset.z };
- }
+ continue;
}
+
+ if (FoundOneBorderingMechanism)
+ {
+ // Case 3
+ return 0;
+ }
+
+ // Potential case 2
+ FoundOneBorderingMechanism = true;
+ PotentialOffset = { -Offset.x, 0, -Offset.z };
}
if (FoundOneBorderingMechanism && (a_QueryPosition != (a_Position + PotentialOffset)))
{
+ // Case 2 fail
return 0;
}
+
+ // Case 1
+ // Case 2 success
}
return (a_Meta != 0) ? --a_Meta : a_Meta;